package l2

import (
	"errors"
	"fmt"

	"zstackgo/pkg/core/componentloader"
	"zstackgo/pkg/header"
	hl2 "zstackgo/pkg/header/network/l2"
	"zstackgo/spring"
)

func init() {
	o := new(L2NetworkExtensionPointEmitter)
	spring.Register(o, "L2NetworkExtensionPointEmitter", []*spring.PluginExtension{
		{
			Interface: "header.Component",
		},
	})
}

var (
	_ header.Component = new(L2NetworkExtensionPointEmitter)
)

type L2NetworkExtensionPointEmitter struct {
	Extensions []hl2.L2NetworkDeleteExtensionPoint
	pluginRgty componentloader.PluginRegistry `autowire:"PluginRegistryImpl"`
}

func (er *L2NetworkExtensionPointEmitter) PreDelete(inv *hl2.L2NetworkInventory) error {
	var err error
	for _, ext := range er.Extensions {
		err = ext.PreDeleteL2Network(inv)
		if err != nil {
			if errors.As(err, hl2.AsL2NetworkException) {
				return err
			} else {
				return fmt.Errorf("Unhandled exception happened while calling L2NetworkDeleteExtensionPoint.preDeleteL2Network of %s", ext.GetClass())
			}
		}
	}

	return nil
}

func (er *L2NetworkExtensionPointEmitter) BeforeDelete(inv *hl2.L2NetworkInventory) {
	for _, ext := range er.Extensions {
		ext.BeforeDeleteL2Network(inv)
	}
}

func (er *L2NetworkExtensionPointEmitter) AfterDelete(inv *hl2.L2NetworkInventory) {
	for _, ext := range er.Extensions {
		ext.AfterDeleteL2Network(inv)
	}
}

func (er *L2NetworkExtensionPointEmitter) Start() error {
	er.populateExtensions()
	return nil
}

func (er *L2NetworkExtensionPointEmitter) populateExtensions() {
	exts := er.pluginRgty.GetExtensionList("L2NetworkDeleteExtensionPoint")
	for _, v := range exts {
		i := v.(hl2.L2NetworkDeleteExtensionPoint)
		er.Extensions = append(er.Extensions, i)
	}
}

func (er *L2NetworkExtensionPointEmitter) Stop() error {
	return nil
}
